
var FSM_State = cc.Class.extend( {
    Name:"BaseState",
    ActiveTime:0.0,
    Target:null,
    fsm:null,
    GoTo:null,
    
    // constructor
    ctor:function( Name, OnEnterFct, OnUpdateFct, OnExitFct, NeedTransitionFct ) {
        if(Name)
            this.Name = Name;
        
        if(OnEnterFct)
            this.OnEnter = OnEnterFct;
        if(OnUpdateFct)    
            this.OnUpdate = OnUpdateFct;
        if(OnExitFct)
            this.OnExit = OnExitFct;
        if(NeedTransitionFct)
            this.NeedTransition = NeedTransitionFct;
    },
    // private like function
    _OnEnter:function(){
        this.ActiveTime = 0.0;
        if(this.OnEnter)
            this.OnEnter();
    },
    _OnUpdate:function(dt){
        this.ActiveTime += dt;
        if(this.OnUpdate)
            this.OnUpdate(dt);
    },
    _OnExit:function(){
        if(this.OnExit)
            this.OnExit();
    },
    _NeedTransition:function(){
        if(this.NeedTransition)
            return this.NeedTransition();
        return false;
    },
    
    // Function To Override
    OnEnter:null,
    OnUpdate:null,
    OnExit:null,
    NeedTransition:null,
} );

var FSM = cc.Class.extend( {
    Target:null,
    PrevState:null,
    ActualState:null,
    NextState:null,
    
    States:{},
    
    
    ctor:function( Target ){
        this.Target = Target;
    },
    
    StartWithState:function(initialState){
        this.ActualState = this.States[ initialState ];
        this.ActualState._OnEnter();
    },
    
    DefineState:function( ListKeyState ){    
        for (var index in ListKeyState) {
            if (ListKeyState.hasOwnProperty(index)){
                
                var state = new FSM_State( index, 
                    ListKeyState[index]["OnEnter"],
                    ListKeyState[index]["OnUpdate"],
                    ListKeyState[index]["OnExit"],
                    ListKeyState[index]["NeedTransition"]
                );
                
                state.Target = this.Target;
                state.fsm = this;
                
                this.States[index] = state;
            }
        }
    },
    
    Update:function(dt){    
        this.ActualState._OnUpdate(dt);
        
        if( this.ActualState._NeedTransition() )
        {
            this.ActualState._OnExit();
            this.ActualState = this.States[ this.ActualState.GoTo ];
            this.ActualState._OnEnter();
        }
    },
} );
